package com.jeecms.cms.api.admin.main;

import com.jeecms.cms.annotation.SignValidate;
import com.jeecms.cms.api.ApiResponse;
import com.jeecms.cms.api.ApiValidate;
import com.jeecms.cms.api.Constants;
import com.jeecms.cms.api.ResponseCode;
import com.jeecms.cms.entity.assist.Branch;
import com.jeecms.cms.manager.main.BranchMng;
import com.jeecms.common.page.Pagination;
import com.jeecms.common.util.StrUtils;
import com.jeecms.common.web.ResponseUtils;
import com.jeecms.core.entity.CmsSite;
import com.jeecms.core.manager.CmsLogMng;
import com.jeecms.core.web.WebErrors;
import com.jeecms.core.web.util.CmsUtils;
import org.apache.commons.lang.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set;

@Controller
public class BranchApiAct {
    private static final Logger log = LoggerFactory.getLogger(BranchApiAct.class);

    @RequestMapping("/branch/get")
    public void get(Integer id,HttpServletRequest request,HttpServletResponse response){
        String body = "\"\"";
        String message = Constants.API_MESSAGE_PARAM_REQUIRED;
        String code = ResponseCode.API_CODE_PARAM_REQUIRED;
        Branch bean;
        if (id!=null) {
            if (id.equals(0)) {
                bean = new Branch();
            }else{
                bean = branchMng.findById(id);
            }
            if (bean!=null) {
                bean.init();
                body = bean.convertToJson(false).toString();
                message = Constants.API_MESSAGE_SUCCESS;
                code = ResponseCode.API_CODE_CALL_SUCCESS;
            }else{
                message = Constants.API_MESSAGE_OBJECT_NOT_FOUND;
                code = ResponseCode.API_CODE_NOT_FOUND;
            }
        }
        ApiResponse apiResponse = new ApiResponse(request, body, message, code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    /**
     * 栏目列表API
     * @param parentId    父栏目ID
     * @param pageNo 当前页码
     * @param pageSize 每页条数
     */
    @RequestMapping(value = "/branch/list")
    public void branchList(Integer parentId, Integer pageNo,Integer pageSize, HttpServletRequest request, HttpServletResponse response){
        String body="\"\"";
        String message=Constants.API_STATUS_FAIL;
        String code = ResponseCode.API_CODE_CALL_SUCCESS;
        if (pageNo==null) {
            pageNo=1;
        }
        if (pageSize==null) {
            pageSize=10;
        }
        Integer siteId = CmsUtils.getSiteId(request);
        int totalCount = 0;
        List<Branch> list;
        if (parentId == null) {
            Pagination page = branchMng.getTopPageForTag(siteId, true, pageNo, pageSize);
            totalCount = page.getTotalCount();
            list = (List<Branch>) page.getList();

        } else {
            Pagination page = branchMng.getChildPageForTag(parentId, true, pageNo, pageSize);
            totalCount = page.getTotalCount();
            list = (List<Branch>) page.getList();
        }
        JSONArray jsonArray=new JSONArray();
        if(list!=null&&list.size()>0){
            for(int i=0;i<list.size();i++){
                jsonArray.put(i, list.get(i).convertToJson(false));
            }
        }
        body=jsonArray.toString() +",\"totalCount\":"+totalCount;;
        message=Constants.API_MESSAGE_SUCCESS;
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

//    @SignValidate
    @RequestMapping(value = "/branch/save")
    public void save(Integer parentId, Branch bean, HttpServletRequest request, HttpServletResponse response){
        String body="\"\"";
        String message=Constants.API_STATUS_FAIL;
        String code = ResponseCode.API_CODE_CALL_FAIL;
        WebErrors errors = WebErrors.create(request);
        //验证公共非空参数
        errors=ApiValidate.validateRequiredParams(request,errors, bean.getName());
        if(bean.getPriority()==null){
            bean.setPriority(10);
        }
        if(!errors.hasErrors()){
            CmsSite site = CmsUtils.getSite(request);
            bean = branchMng.save(bean, site, parentId, false);
            log.info("save Channel id={}, name={}", bean.getId(), bean.getName());
            cmsLogMng.operating(request, "branch.log.save", "id=" + bean.getId()
                    + ";title=" + bean.getName());
            body="{\"id\":"+"\""+bean.getId()+"\"}";
            message=Constants.API_MESSAGE_SUCCESS;
            code = ResponseCode.API_CODE_CALL_SUCCESS;
        }else{
            message=Constants.API_MESSAGE_PARAM_REQUIRED;
            code = ResponseCode.API_CODE_PARAM_ERROR;
        }
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    @RequestMapping(value = "/branch/update", method = RequestMethod.POST)
    public void update(Integer parentId, Branch bean, HttpServletRequest request, HttpServletResponse response){
        String body="\"\"";
        String message=Constants.API_STATUS_FAIL;
        String code = ResponseCode.API_CODE_CALL_FAIL;
        WebErrors errors = validateUpdate(bean.getId(), request);
        //验证公共非空参数
        errors=ApiValidate.validateRequiredParams(request,errors, bean.getName());
        if(bean.getPriority()==null){
            bean.setPriority(10);
        }
        if(!errors.hasErrors()){
            CmsSite site = CmsUtils.getSite(request);
            bean = branchMng.update(bean, site.getId(), parentId, false);
            log.info("update Branch id={}.", bean.getId());
            cmsLogMng.operating(request, "branch.log.update", "id=" + bean.getId()
                    + ";name=" + bean.getName());
            body="{\"id\":"+"\""+bean.getId()+"\"}";
            message=Constants.API_MESSAGE_SUCCESS;
            code = ResponseCode.API_CODE_CALL_SUCCESS;
        }
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    @SignValidate
    @RequestMapping("/branch/delete")
    public void delete(String ids, HttpServletRequest request, HttpServletResponse response) {
        Integer[]idArray=null;
        String body="\"\"";
        String message=Constants.API_STATUS_FAIL;
        String code = ResponseCode.API_CODE_CALL_FAIL;
        WebErrors errors=WebErrors.create(request);
        //验证公共非空参数
        errors=ApiValidate.validateRequiredParams(request,errors,ids);
        if(StringUtils.isNotBlank(ids)){
            idArray=StrUtils.getInts(ids);
        }
        if(idArray==null||idArray.length<=0){
            errors.addErrorString(Constants.API_MESSAGE_APP_PARAM_ERROR);
            message=Constants.API_MESSAGE_PARAM_REQUIRED;
            code = ResponseCode.API_CODE_PARAM_ERROR;
        }else{
            errors = validateDelete(idArray, request);
            message=Constants.API_MESSAGE_DELETE_ERROR;
            code = ResponseCode.API_CODE_DELETE_ERROR;
        }
        if(!errors.hasErrors()){
            try {
                Branch[] beans = branchMng.deleteByIds(idArray);
                message=Constants.API_MESSAGE_SUCCESS;
                code = ResponseCode.API_CODE_CALL_SUCCESS;
                for (Branch bean : beans) {
                    log.info("delete Channel id={}", bean.getId());
                    cmsLogMng.operating(request, "channel.log.delete", "id="
                            + bean.getId() + ";title=" + bean.getName());
                }
            } catch (Exception e) {
                message = Constants.API_MESSAGE_DELETE_ERROR;
                code = ResponseCode.API_CODE_DELETE_ERROR;
            }
        }
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    @RequestMapping("/branch/tree")
    public void tree(String root, Integer https,HttpServletRequest request,
                     HttpServletResponse response){
        boolean isRoot;
        // jquery treeview的根请求为root=source
        if (StringUtils.isBlank(root) || "source".equals(root)) {
            isRoot = true;
        } else {
            isRoot = false;
        }
        if(https==null){
            https=Constants.URL_HTTP;
        }
        List<Branch> list;
        Integer siteId = CmsUtils.getSiteId(request);
        if (isRoot) {
            //获取一级目录
            list = branchMng.getTopList( siteId, false);
        } else {
            list = branchMng.getChildList(Integer.parseInt(root), false);
        }

        JSONArray jsonArray=new JSONArray();
        if(list!=null&&list.size()>0){
            for(int i=0;i<list.size();i++){
                jsonArray.put(i, list.get(i).convertToJson(false));
            }
        }
        String body=jsonArray.toString();
        String message=Constants.API_MESSAGE_SUCCESS;
        String code = ResponseCode.API_CODE_CALL_SUCCESS;
        ApiResponse apiResponse=new ApiResponse(request, body, message, code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    @RequestMapping("/branch/select")
    public void branchSelect(Boolean hasContentOnly,Integer excludeId,
                              HttpServletRequest request,HttpServletResponse response){
        CmsSite site = CmsUtils.getSite(request);
        if (hasContentOnly==null) {
            hasContentOnly=true;
        }
        List<Branch> topList = branchMng.getTopList(site.getId(), hasContentOnly);
        JSONArray jsonArray = new JSONArray();
        if (topList!=null&&topList.size()>0) {
            int k=0;
            for(int i = 0 ; i<topList.size(); i++){
                JSONObject json=createSelectJson(topList.get(i),excludeId);
                if(null != json){
                    jsonArray.put(k,json);
                }else{
                    k--;
                }
                k++;
            }
        }
        String body = jsonArray.toString();
        String message = Constants.API_MESSAGE_SUCCESS;
        String code = ResponseCode.API_CODE_CALL_SUCCESS;
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }


    @RequestMapping(value = "/branch/getBranchs")
    public void getBranchs(Integer https, HttpServletRequest request,HttpServletResponse response){
        String body="\"\"";
        String message=Constants.API_STATUS_FAIL;
        String code=ResponseCode.API_CODE_CALL_SUCCESS;
        List<Branch> branches = branchMng.getTopList(CmsUtils.getSiteId(request), true);
        JSONArray branchs = new JSONArray();
        for(Branch b : branches){
            JSONObject parent = new JSONObject();
            parent.put("id", b.getId());
            parent.put("label", b.getName());
            parent.put("children", getChildJson(b));
            branchs.put(parent);
        }
        body = branchs.toString() ;
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    private JSONArray getChildJson(Branch branch){
        JSONArray array = new JSONArray();
        if(branch.getChild()!=null && branch.getChild().size() >0){//子集
            for(Branch b : branch.getChild()){
                JSONObject parent = new JSONObject();
                parent.put("id", b.getId());
                parent.put("label", b.getName());
                parent.put("children", getChildJson(b));
                array.put(parent);
            }
        }
        return array;
    }

    private JSONObject createSelectJson(Branch branch,Integer excludeId) {
        JSONObject json = new JSONObject();
        if(branch!=null){
            if(excludeId==null||(excludeId!=null&&!branch.getId().equals(excludeId))){
                if (branch.getId()!=null) {
                    json.put("id", branch.getId());
                }else{
                    json.put("id", "");
                }
                if (StringUtils.isNotBlank(branch.getName())) {
                    json.put("name", branch.getName());
                }else{
                    json.put("name", "");
                }
                if (branch.getChild() != null && branch.getChild().size()>0) {
                    json.put("hasChild", true);
                    Set<Branch> child = branch.getChild();
                    JSONArray jsonArray = new JSONArray();
                    int index = 0 ;
                    for (Branch c : child) {
                        JSONObject jsonObj=createSelectJson(c,excludeId);
                        if(jsonObj!=null){
                            jsonArray.put(index,jsonObj);
                        }else{
                            index--;
                        }
                        index++;
                    }
                    json.put("child", jsonArray);
                }else{
                    json.put("hasChild", false);
                }
            }else{
                //清空对象，否则前端还是多个空对象
                json=null;
            }
        }else{
            json=null;
        }
        return json;
    }

    @SignValidate
    @RequestMapping("/branch/priority")
    public void priority(String ids, String prioritys, HttpServletRequest request, HttpServletResponse response) {
        String body="\"\"";
        String message=Constants.API_STATUS_FAIL;
        String code = ResponseCode.API_CODE_CALL_FAIL;
        WebErrors errors=WebErrors.create(request);
        //验证公共非空参数
        errors=ApiValidate.validateRequiredParams(request,errors,ids,prioritys);
        Integer[] idInts=null,priorityInts=null;
        if(StringUtils.isNotBlank(ids)){
            idInts=StrUtils.getInts(ids);
            priorityInts=StrUtils.getInts(prioritys);
        }
        if(idInts==null||idInts.length<=0|| priorityInts==null||priorityInts.length<=0){
            errors.addErrorString(Constants.API_MESSAGE_PARAM_REQUIRED);
            log.info("未选中");
        }
        if(!errors.hasErrors()){
            errors= validatePriority(idInts, priorityInts, request);
        }
        if(!errors.hasErrors()){
            branchMng.updatePriority(idInts, priorityInts);
            message=Constants.API_MESSAGE_SUCCESS;
            code = ResponseCode.API_CODE_CALL_SUCCESS;
        }
        ApiResponse apiResponse=new ApiResponse(request, body, message,code);
        ResponseUtils.renderApiJson(response, request, apiResponse);
    }

    private WebErrors validatePriority(Integer[] wids, Integer[] priority,
                                       HttpServletRequest request) {
        CmsSite site = CmsUtils.getSite(request);
        WebErrors errors = WebErrors.create(request);
        if (errors.ifEmpty(wids, "wids", false)) {
            log.info("未选中");
            return errors;
        }
        if (errors.ifEmpty(priority, "priority", false)) {
            return errors;
        }
        if (wids.length != priority.length) {
            errors.addErrorString(Constants.API_MESSAGE_PARAM_ERROR);
            return errors;
        }
        for (int i = 0, len = wids.length; i < len; i++) {
            if (vldExist(wids[i], site.getId(), errors)) {
                return errors;
            }
            if (priority[i] == null) {
                priority[i] = 0;
                log.info("0");
            }
        }
        return errors;
    }

    private WebErrors validateUpdate(Integer id, HttpServletRequest request) {
        WebErrors errors = WebErrors.create(request);
        CmsSite site = CmsUtils.getSite(request);
        if (vldExist(id, site.getId(), errors)) {
            return errors;
        }
        return errors;
    }

    private boolean vldExist(Integer id, Integer siteId, WebErrors errors) {
        if (errors.ifNull(id, "id", false)) {
            return true;
        }
        Branch entity = branchMng.findById(id);
        if (errors.ifNotExist(entity, Branch.class, id, false)) {
            return true;
        }
        if (!entity.getSite().getId().equals(siteId)) {
            errors.addErrorString("error.notInSite");
            return true;
        }
        return false;
    }

    private WebErrors validateDelete(Integer[] ids, HttpServletRequest request) {
        WebErrors errors = WebErrors.create(request);
        CmsSite site = CmsUtils.getSite(request);
        errors.ifEmpty(ids, "ids", false);
        for (Integer id : ids) {
            if (vldExist(id, site.getId(), errors)) {
                log.info("不存在");
                return errors;
            }
            // 检查是否可以删除1
            String code = branchMng.checkDelete(id);
            if (code != null) {
                errors.addErrorString(code);
                return errors;
            }
        }
        return errors;
    }

    @Autowired
    private BranchMng branchMng;

    @Autowired
    private CmsLogMng cmsLogMng;
}
